/*
 * Copyright 2013-2019 Xia Jun(3979434@qq.com).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ***************************************************************************************
 *                                                                                     *
 *                        Website : http://www.farsunset.com                           *
 *                                                                                     *
 ***************************************************************************************
 */
package com.workcell.workdata.im.service.impl;

import com.workcell.workdata.im.component.cim.pusher.MessagePusherProxy;
import com.workcell.workdata.im.component.event.GroupEvent;
import com.workcell.workdata.im.component.event.RobotTransferEvent;
import com.workcell.workdata.im.constant.MessageAction;
import com.workcell.workdata.im.constant.RobotState;
import com.workcell.workdata.im.entity.GroupMessage;
import com.workcell.workdata.im.entity.GroupRobot;
import com.workcell.workdata.im.entity.Message;
import com.workcell.workdata.im.model.app.Origin;
import com.workcell.workdata.im.model.dto.MessageTitle;
import com.workcell.workdata.im.model.request.RobotMessageRequest;
import com.workcell.workdata.im.model.response.ResponseEntity;
import com.workcell.workdata.im.model.vo.GroupRobotVO;
import com.workcell.workdata.im.repository.GroupMessageRepository;
import com.workcell.workdata.im.repository.GroupRepository;
import com.workcell.workdata.im.repository.GroupRobotRepository;
import com.workcell.workdata.im.service.GroupRobotService;
import com.workcell.workdata.im.util.JSON;
import com.workcell.workdata.im.util.PageX;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.event.EventListener;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Service
public class GroupRobotServiceImpl implements GroupRobotService {

	@Resource
	private GroupRobotRepository groupRobotRepository;

	@Resource
	private ApplicationContext applicationContext;

	@Resource
	private MessagePusherProxy messagePusherProxy;

	@Resource
	private GroupMessageRepository groupMessageRepository;

	@Resource
	private GroupRepository groupRepository;

	@Override
	public void add(GroupRobot robot) {

		robot.setState(RobotState.ENABLE);
		robot.setCreateTime(new Date());
		String uuid = UUID.randomUUID().toString().replace("-","");
		robot.setUuid(uuid.toUpperCase());
		groupRobotRepository.saveAndFlush(robot);


		GroupEvent event = new GroupEvent(robot.getGroupId(),robot.getUid());
		event.addIgnored(robot.getUid());
		event.setAction(MessageAction.ACTION_313);

		Map<String,Object> content = new HashMap<>();
		content.put("id"  ,robot.getId());
		content.put("name",robot.getName());

		event.setContent(JSON.toJSONString(content));

		applicationContext.publishEvent(event);

	}


	@Override
	public void update(GroupRobot robot) {
		GroupRobot target = groupRobotRepository.findById(robot.getId()).orElse(null);
		if (target == null){
			return;
		}

		target.setName(robot.getName());
		target.setWebhook(robot.getWebhook());

		groupRobotRepository.saveAndFlush(target);

		GroupEvent event = new GroupEvent(target.getGroupId(),target.getUid());

		event.setAction(MessageAction.ACTION_314);
		event.setContent(String.valueOf(robot.getId()));
		event.setReplaceable(false);
		applicationContext.publishEvent(event);
	}

	@Override
	public GroupRobotVO findOne(long id) {
		return GroupRobotVO.of(groupRobotRepository.findById(id).orElse(null));
	}


	@Override
	public void disable(long id,long uid) {

		groupRobotRepository.disable(id);

		Long groupId = groupRobotRepository.findGroupId(id);

		GroupEvent event = new GroupEvent(groupId,uid);
		event.addIgnored(uid);
		event.setAction(MessageAction.ACTION_317);
		event.setContent(String.valueOf(id));
		event.setExtra(String.valueOf(RobotState.DISABLED));
		applicationContext.publishEvent(event);
	}

	@Override
	public void enable(long id,long uid) {

		groupRobotRepository.enable(id);

		Long groupId = groupRobotRepository.findGroupId(id);

		GroupEvent event = new GroupEvent(groupId,uid);
		event.addIgnored(uid);
		event.setAction(MessageAction.ACTION_317);
		event.setContent(String.valueOf(id));
		event.setExtra(String.valueOf(RobotState.ENABLE));
		applicationContext.publishEvent(event);
	}

	@Override
	public void transfer(List<Long> uidList, long groupId) {

		List<Long> idList = groupRobotRepository.findIdList(groupId,uidList);

		if (idList.isEmpty()){
			return;
		}

		/*
		 * 这些人名下机器人转让给群主
		 */
		long uid = groupRepository.findUid(groupId);

		groupRobotRepository.transfer(idList,uid);

		GroupEvent event = new GroupEvent(groupId);
		event.setAction(MessageAction.ACTION_319);
		event.setContent(StringUtils.join(idList,","));
		event.setExtra(String.valueOf(uid));

		applicationContext.publishEvent(event);
	}

	@EventListener(classes = RobotTransferEvent.class)
	public void onTransferEvent(RobotTransferEvent event){
		this.transfer(event.getUidList(),event.getGroupId());
	}

	@Override
	public void remove(long groupId) {
		groupRobotRepository.remove(groupId);
	}

	@Override
	public List<GroupRobotVO> findList(long groupId) {
		return PageX.map(GroupRobotVO::of,groupRobotRepository.findList(groupId));
	}

	@Override
	public List<GroupRobotVO> findList(List<Long> groupIdList) {
		return PageX.map(GroupRobotVO::of,groupRobotRepository.findList(groupIdList));
	}

	@Override
	public ResponseEntity<Void> send(String uuid, RobotMessageRequest request) {

		GroupRobot robot = groupRobotRepository.findByUuid(uuid);

		boolean isPushable = robot != null && robot.getState() == RobotState.ENABLE;

		if (!isPushable){
			return ResponseEntity.make(HttpStatus.BAD_REQUEST,"机器人不存在或已经禁用");
		}

		Message message = new GroupMessage();
		message.setReceiver(robot.getGroupId());
		message.setAction(MessageAction.ACTION_4);
		message.setSender(robot.getId());
		message.setContent(request.getContent());
		message.setFormat(request.getFormat());

		MessageTitle title = new MessageTitle();
		title.setQt(request.getMessageId());
		title.setName(robot.getName());
		message.setTitle(JSON.toJSONString(title));

		messagePusherProxy.push(message, Origin.UNKNOWN);

		return ResponseEntity.ok();
	}

	@Override
	public ResponseEntity<Void> delete(long id,long uid) {
		GroupRobot robot = groupRobotRepository.findById(id).orElse(null);
		if (robot == null || robot.getUid() != uid){
			return ResponseEntity.make(HttpStatus.BAD_REQUEST,"你没有权限删除该机器人");
		}

		groupRobotRepository.deleteById(id);

		groupMessageRepository.deleteAll(robot.getGroupId(),robot.getId(),MessageAction.ACTION_4);

		GroupEvent event = new GroupEvent(robot.getGroupId());
		event.setAction(MessageAction.ACTION_316);
		event.setContent(String.valueOf(id));
		event.setReplaceable(false);
		applicationContext.publishEvent(event);

		return ResponseEntity.ok();
	}

}
